/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			irenderer.d
	Description:	interface for rendering subsystems
	Date:			11.04.2008 by Digited
*/
module moonglide.renderer.IRenderer;

public import
	moonglide.os.IOS,

	moonglide.renderer.IRendererOS,
	moonglide.renderer.IRendererRes,
	moonglide.renderer.IRendererBind,
	moonglide.renderer.IRendererOffscreen,
	moonglide.renderer.IRendererMatSys;

import
	moonglide.core.engobjects.EngObject,
	moonglide.core.engobjects.EngSprite,
	moonglide.core.engobjects.EngCamera,
	moonglide.core.engobjects.EngLight,
	moonglide.core.engobjects.EngGeometry,
	moonglide.core.engobjects.EngRawData,
	moonglide.core.engobjects.EngParSystem;


//	moonglide.core.EngObjects;

//===============================================================
/// enumeration of supported rendering subsystems
//===============================================================
enum DRIVERTYPE
{
	DT_OPENGL = 0,	/// opengl
	DT_D3D9			/// direct3d9
}

//===============================================================
/// enumeration of supported rendering subsystems
//===============================================================
class CFpsCounter
{
	protected:
		float
			_framecounter = 0.0,
			_timer = 0.0,
			_fps = 0.0,
			_lastFrameTime = 0.0;

		uint _totalFrames;

	public:
		uint getTotalFrames() { return _totalFrames; }
		float getLastFrametime()
		{
		    return _lastFrameTime;
		}

		/// add frametime and increase frame counter. If counted time > 1.0, CalcFPS() is called
		void addFrameTime( float frametime )
		{
		    _lastFrameTime = frametime;
			_totalFrames++;

			_framecounter++;
			_timer += frametime;

			if( _timer >= 2000.0 )
			{
				calcFPS();
			}
		}

		/// simple fps counter
		void calcFPS()
		{
			if( _timer != 0.0 )
			{
				_fps = (_framecounter / _timer) * 1000.0;
				_timer -= 2000.0;
			}
			else
				_fps = 0.0;

			_framecounter = 0;
		}

		/// returns last counted fps
		float fps() { return _fps; }
}


//===============================================================
/// IRenderer - abstract class for rendering subsystems
//===============================================================
abstract class IRenderer
{
    protected:
        Size2ui				xviewport;

	public:
		SRawData[]			xRawData; // raw data (primitive arrays)
		CEngLight[] 		xLight; // lights that use is in scene
		CEngGeometry[]		xGeom;	// geometry, that need to be rendered
		CEngSprite[]		xSpr;	// sprites
		CEngParSystem[]		xParSys;// par system

		CEngGeometry		curGeom;
		CEngCamera			curCam;

		Size2ui				viewport()
		{
		    return xviewport;
		}
		void                viewport(Size2ui v)
		{
		    xviewport = v;
		    if( curCam )
		    {
                curCam.viewport = xviewport;
                setActiveCamera( curCam );
		    }
		}

		CFpsCounter			fpsCounter;
		IRendererOS 		osDependent;

		IRendererRes		resLoader;
		IOffscreenManager	offscreenMan;
		IMaterialSys		materialSys;

		void clearArrays()
		{
			xLight.length = 0;
			xGeom.length = 0;
			xSpr.length = 0;
			xParSys.length = 0;
			xRawData.length = 0;
		}

		/// for shader system:
		Vector4f getActiveWorGeomPos();
		Vector4f getActiveWorLightPos();
		Vector4f getActiveWorCameraPos();

		Vector4f getActiveModelwGeomPos();
		Vector4f getActiveModelwLigthPos();

		Vector4f getActiveObjLigthPos();
		Vector4f getActiveObjCameraPos();
		////////////////////////////////////////////////////

		/// initialize: make window and startup device
		bool 	initialize( IOS ios, char[] windowtitle, Size2ui windowsize, ubyte bpp,
					ubyte refreshFreq, bool fullscreen, bool vsync, bool antialiasing, bool stencil );

		bool	deInitialize();						/// shutdown all

		void	startScene();						/// clears surface, buffers and object arrays
		void	render();							/// make a frame
		bool	presentFrame();						/// swaps buffers

		void	setActiveCamera( CEngCamera cam );	/// set projection params for current rendering pass
		bool	saveScreenshot();					/// make and save a screenshot

		debug	void DbgReport();

		/// must be in GUI
		void fullScreenQuad();
        void init2DEngine();
        void deInit2DEngine();
        ///
}
